#!/usr/bin/env python3
# coding: utf-8
"""
2024-02-19 
"""
from PySide6.QtWidgets import QTableWidget, QTableWidgetItem, QHeaderView, QAbstractItemView, QApplication, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy,QTableView,QMessageBox
from PySide6.QtCore import QSize,QModelIndex
from PySide6.QtWidgets import QStyledItemDelegate, QStyleOptionViewItem, QApplication
from PySide6.QtGui import QPainter

class LongTextDelegate(QStyledItemDelegate):
    def paint(self, painter: QPainter, option: QStyleOptionViewItem, index):
        text = index.model().data(index, Qt.DisplayRole)
        painter.drawText(option.rect, Qt.AlignLeft | Qt.AlignVCenter, text)

from top.wardyan.core.vo.vos import Record, TableCfg, TableColCfg
## from top.wardyan.core.
from top.wardyan.core.utils.tableutil import *
## from top.wardyan.core.vo
## from top.wardyan.core.utils import winformutils
## from top.wardyan.core.widges import tablemanager


from PySide6.QtGui import QStandardItemModel, QStandardItem,QColor,QBrush
from PySide6.QtCore import Qt, Signal, Slot, QEvent, QTime
from PySide6.QtGui import QAction

from dateutil.parser import parse







class WBaseTableView(QTableView) :
    """
    2024-06-09  F 还想要能保存配置
    """

    BACKGROUND_COLOR_AUDUT = QBrush(QColor(0, 0, 128))
    BACKGROUND_COLOR_CHECK = QBrush(QColor(218,112,214))
    BACKGROUND_COLOR_MENDER = QBrush(QColor(144,238,144))
    BACKGROUND_COLOR_EDIT = QBrush(QColor(173,216,230))
    BACKGROUND_COLOR_DRAFT = QBrush(QColor(255,250,205))
    BACKGROUND_COLOR_VOID = QBrush(QColor(200,200,200))

    FRONT_COLOR_AUDUT = QBrush(QColor(255, 255, 255))
    FRONT_COLOR_CHECK = QBrush(QColor(255,255,255))
    FRONT_COLOR_MENDER = QBrush(QColor(0,0,0))
    FRONT_COLOR_EDIT = QBrush(QColor(255,255,255))
    FRONT_COLOR_DRAFT = QBrush(QColor(0,0,0))
    FRONT_COLOR_VOID = QBrush(QColor(0,0,0))

    
    FRONT_COLOR_DEFAULT = QBrush(QColor(0,0,0))
    BACKGROUND_COLOR_DEFAULT = QBrush(QColor(255,255,255))


    widgetname : str
    tablename : str
    model : QStandardItemModel
    fields : list[str] = []
    cfg : TableCfg = None
    _data_ = None
    _keyword_ = ""

    _col_idx_ = {}

    handle_double_click = None
    
    def __init__(self, parent, widgetname : str, tablename : str, data : list[Record] = [], dbclick = None) :
        QTableView.__init__(self, parent)
        if data is None :
            data = []
        self._data_ = data
        self.widgetname = widgetname
        self.tablename = tablename
        self._config()
        self.render(data)
        self.horizontalHeader().sectionMoved.connect(self.on_section_moved)
        ## 行双击事件

        # 初始化上次点击时间和上次点击的行索引
        self.last_click_time = None
        self.last_clicked_row = None

        self.handle_double_click = dbclick
        if self.handle_double_click is not None :
            self.doubleClicked.connect(self.handle_double_click)
        
    def on_section_moved(self, logicalIndex, oldVisualIndex, newVisualIndex):
        """
        当列被移动后调用的槽函数。
        :param logicalIndex: 逻辑索引，即未改变的列索引
        :param oldVisualIndex: 列移动前的视觉索引
        :param newVisualIndex: 列移动后的视觉索引
        """
        #print(f"Column {logicalIndex} moved from {oldVisualIndex} to {newVisualIndex}.")
        pass

    @Slot()
    def autocolumnwidth(self) :
        header = self.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
        ## 保存配置
        self.saveconfigs()

        ## 重新显示数据
        self.render(self._data_, self._keyword_)
        ## 再次允许双击列边框调整列宽
        header.setSectionResizeMode(QHeaderView.ResizeMode.Interactive)



    @Slot()
    def slot_resettablecol(self) :
        clearTableCfg(widgetname=self.widgetname, tablename=self.tablename)
        # ##self._config()
        # ## 重新读取
        # self._config()
        # ## 提示
        # #self.parent().showMessage("表格列已重置")
        self.buildColumns(self._data_, True)
        self._config()
        self.render(self._data_, self._keyword_)
        QMessageBox.information(self, "提示", "表格列已重置")


    def _config(self) :
        """
        从配置里读取
        """
        self.setModel(None)
        ## self.model.setHorizontalHeaderLabels([])
        self.fields = []
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        ## self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
        self.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
        ## cfg : TableCfg = readTableCfg(self.widgetname, self.tablename)
        self.cfg  = readTableCfg(self.widgetname, self.tablename)
        
        self.model = QStandardItemModel()
        ## self.model.clear()
        self.setModel(self.model)
        hs = []
        if self.cfg is not None :
            self.rh = self.cfg.height
            ## self.rh = 
            cols = self.cfg.cols
            colcnt = 0
            for c in cols :
                if c.show :
                    colcnt += 1
                    hs.append(c.title)
            self.model.setColumnCount(colcnt)
            idx : int = 0
            for c in cols :
                # if c.show :
                if True :
                    title : str = c.title
                    field : str = c.field
                    width : int = c.width
                    item : QStandardItem = QStandardItem(title)
                    item.field = field
                    if c.show :
                        self.setColumnWidth(idx, width)
                    else :
                        self.setColumnWidth(idx, 0)
                    self.model.setHorizontalHeaderItem(idx, item)
                    self.fields.append(field)
                    self._col_idx_[field] = idx
                    idx += 1
        
        header = self.horizontalHeader()
        header.setSectionsMovable(self.cfg.colmoveable)
        ## 菜单
        self.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
        self._saveconfigs = QAction('保存表格配置')
        self._saveconfigs.triggered.connect(self.slot_saveconfigs)
        ## 
        self.initautocolumwidth = QAction('自动列宽')
        self.initautocolumwidth.triggered.connect(self.autocolumnwidth)
        self.addActions([self._saveconfigs,self.initautocolumwidth])


        ## 
        self.resettablecol = QAction('重置表格列')
        self.resettablecol.triggered.connect(self.slot_resettablecol)
        self.addActions([self.initautocolumwidth,self.resettablecol])

        ## 设置列宽和对齐方式,格式化,替换值

    

    @Slot()
    def slot_saveconfigs(self) :
        self.saveconfigs()
        ## 重新显示数据
        self.render(self._data_, self._keyword_)

    def saveconfigs(self):
        cfg : TableCfg = readTableCfg(self.widgetname, self.tablename)
        cfg.name = self.tablename
        
        cnt : int = self.model.columnCount()
        model = self.model
        # for column in range(cnt):
        #      width = self.columnWidth(column)
        idx = 1
        oks = []
        for column in range(cnt):
            visualcolumnidx = self.horizontalHeader().visualIndex(column)
            width = self.columnWidth(column)
            item : QStandardItem = model.horizontalHeaderItem(column)
            field : str = item.field
            c : TableColCfg = cfg.getColCfg(field)
            c.width = width
            c.title = item.text()
            if width > 0 :
                c.show = True
            else :
                c.show = False
            c.idx = visualcolumnidx
            idx += 1
            oks.append(c)
        cfg.cols = oks
        saveTableCfg(widgetname=self.widgetname, tablename=self.tablename, cfg=cfg)
        ##self._config()
            

        



    def buildColumns(self, data : list[Record], rebuild = False) -> None :
        """
        建立列
        要区分: 在原有基础上新增栏位, 还是清掉重来
        """
        cfg : TableCfg = readTableCfg(self.widgetname, self.tablename)
        cfg.name = self.tablename

        cnt : int = self.model.columnCount()
        if ( cnt is None or cnt < 1  ) and (data is not None and len(data) > 0):
            ## TODO
            logger.debug("生成table列,widgetname:" + self.widgetname + ",tablename:" + self.tablename)
            cfg.fields = []
            cfg.height = 30
            cfg.cols = []
            d = data[0]
            idx = 1
            for key in d.keys() :
                cfg.fields.append(key)
                sector = "col_" + self.tablename + "_" + key
                c : TableColCfg = TableColCfg()
                c.field = key
                c.title = key
                c.align = 0
                c.width = 120
                c.show = True
                c.replace = ""
                c.datatype = 0
                c.format = ""
                c.idx = idx
                cfg.cols.append(c)
                idx += 1
                
            saveTableCfg(widgetname=self.widgetname, tablename=self.tablename, cfg=cfg)
            self._config()
    # def getColCfg(cfg : TableCfg , field : str) -> str :
    #     rs = ""
    #     for c in cfg.cols :
    #         if c.field == field :
    #             return c
    #     return rs


    def rowcolor(self, value : str):
        a = self.BACKGROUND_COLOR_DEFAULT
        b = self.FRONT_COLOR_DEFAULT
        if value == "锁定" or value == "审核" :
            b = self.FRONT_COLOR_AUDUT
            a = self.BACKGROUND_COLOR_AUDUT
        elif value == "复核" :
            b = self.FRONT_COLOR_CHECK
            a = self.BACKGROUND_COLOR_CHECK
        elif value == "提交" :
            b = self.FRONT_COLOR_MENDER
            a = self.BACKGROUND_COLOR_MENDER
        elif value == "编辑" :
            b = self.FRONT_COLOR_EDIT
            a = self.BACKGROUND_COLOR_EDIT
        elif value == "草稿" :
            b = self.FRONT_COLOR_DRAFT
            a = self.BACKGROUND_COLOR_DRAFT
        elif value == "作废" :
            b = self.FRONT_COLOR_VOID
            a = self.BACKGROUND_COLOR_VOID
        return a, b

    def render(self, data : list[Record], keyword : str = "") : 


        if data is None :
            data = []
        self._data_ = data
        self._keyword_ = keyword
        delegate = LongTextDelegate()
        self.setItemDelegate(delegate)

        ## print("datalen", len(data), self._data_)
        
        cfg : TableCfg = readTableCfg(self.widgetname, self.tablename)
        cfg.name = self.tablename

        cols = cfg.getColCfgs()
        
        # preidx = 0

        # selectedmodel = self.selectionMode()
        # if selectedmodel is not None and selectedmodel.hasSelection() :
        #         preidx = selectedmodel.selectedIndexes()

        # if data is None or len(data) < 1 :
        #     return

        
        ## if self.model.columnCount() < 1 :
        if cols is None or len(cols) < 1 :
            self.buildColumns(data, False)
            cfg : TableCfg = readTableCfg(self.widgetname, self.tablename)
            cfg.name = self.tablename

            cols = cfg.getColCfgs()
            
        ## self.model.clear()
        ## self.model.clearItemData()
        
        rowcnt = len(data)
        self.model.setRowCount(rowcnt)
        rowidx = 0
        for d in data :
            i : int = 0
            row_background_color = self.BACKGROUND_COLOR_DEFAULT
            row_front_color = self.FRONT_COLOR_DEFAULT

            if "sStatus" in self.fields and self.cfg.rowcolor :
                for field in self.fields :
                    if field == "sStatus" :
                        value = d.getStr(field)
                        col : TableColCfg = cols[field]
                        k = str(value)
                        if col is not None and hasattr(col, "_replaces") and col._replaces is not None and k in col._replaces :
                            value = col._replaces[k]
                        ## 数据类型 0文本 1整型 2浮点 3日期时间 4布尔 5日期
                        # if col.datatype == 3 :
                        #     if value is not None :
                        #         value = parse(value).strftime("%Y-%m-%d %H:%M:%S")
                        #     else :
                        #         value = ""
                        # elif col.datatype == 5 :
                        #     if value is not None :
                        #         value = parse(value).strftime("%Y-%m-%d")
                        #     else :
                        #         value = ""
                        
                        # if value == "None" or value is None or str(value) == "0" :
                        #     value = ""

                        if field == "sStatus" :
                            row_background_color, row_front_color = self.rowcolor(value)

            ##



            for field in self.fields :
                value = d.getStr(field)
                # 检查字段是否存在于列配置中，如果不存在则跳过
                if field not in cols:
                    continue
                col : TableColCfg = cols[field]
                k = str(value)
                if col is not None and hasattr(col, "_replaces") and col._replaces is not None and k in col._replaces :
                    value = col._replaces[k]

                ## 数据类型 0文本 1整型 2浮点 3日期时间 4布尔 5日期
                if col.datatype == 3 :
                    if value is not None and value != 'None' :
                        value = parse(value).strftime("%Y-%m-%d %H:%M:%S")
                    else :
                        value = ""
                elif col.datatype == 4 :
                    if value is not None and value != 'None' :
                        if k in col._replaces :
                            value = col._replaces[k]
                        else :
                            if value == "1" or str == "true" or str == "True" :
                                value = "√"
                            else :
                                value = value
                    else :
                        value = ""
                elif col.datatype == 5 :
                    if value is not None and value != 'None' :
                        value = parse(value).strftime("%Y-%m-%d")
                    else :
                        value = ""
                
                if value == "None" or value is None or str(value) == "0" :
                    value = ""
                c : QStandardItem = QStandardItem(value)
                c.setForeground(row_front_color)
                c.setBackground(row_background_color)
                tooltip : str = value
                if tooltip is not None and len(tooltip) > 200 :
                    tooltip = tooltip[0:200] + "..."
                c.setToolTip(tooltip)
                c.setText(value)
                

                ## s开头的字段一律居中
                ## 对齐方式 0默认左对齐 1居中 2右对齐
                if field.startswith("s") or col.align == 1 or col.datatype == 4 :
                    c.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
                elif col.align == 2 :
                    c.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
                else :
                    c.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter)
                ## c.setTextAlignment(Qt.AlignCenter)


                self.model.setItem(rowidx, i, c)
                i += 1
            self.setRowHeight(rowidx, self.rh)
            rowidx += 1
        self.search(keyword=keyword)

    def search(self, keyword : str = "") :
        if keyword is None :
            keyword = ""
        if not keyword == "" :
            for i in range(0, self.model.rowCount()) :
                finded : bool = False
                for j in range(0, self.model.columnCount()) :
                    item : QStandardItem = self.model.item(i, j) 
                    t : str = item.text()
                    if keyword in t :
                        finded = True
                        break
                if not finded :
                    self.hideRow(i)
                else :
                    self.showRow(i)
        """
        ## 自动列宽
        header = self.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
        """
    def get_row_data(self, row : int) -> Record:
        """"
        获取指定行的所有数据。
        暂不支持行排序 TODO
        :param row: 要获取数据的行的索引。
        :return: 一个列表，包含该行每一列的数据。
        
        """
        rs : Record = Record()
        ##model = self.model()  # 获取表格模型
        if self._data_ is None or len(self._data_) == 0:  
            return None  # 如果模型未设置，则返回空列表
        datas : list[Record] = self._data_
        if row >= len(datas) :
            return None
        data = datas[row]
        if data is None :
            return None
        return data
        # for column in range(column_count):
        #     index = model.index(row, column)  # 获取该行该列的索引
        #     data = model.data(index)  # 获取数据
        #     data_list.append(data)
        
        # return data_list